Skip to content

feat: Add redis caching, ttl, on initial endpoints#280

Open
zaydaanjahangir wants to merge 5 commits intomainfrom
feat/feat-redis-caching-phase-1
Open

feat: Add redis caching, ttl, on initial endpoints#280
zaydaanjahangir wants to merge 5 commits intomainfrom
feat/feat-redis-caching-phase-1

Conversation

@zaydaanjahangir
Copy link
Copy Markdown
Contributor

@zaydaanjahangir zaydaanjahangir commented Apr 4, 2026

Cached endpoints:

  • GET /api/v1/users/:id
  • GET /api/v1/hotels/:id
  • GET /api/v1/guests/:id
  • GET /api/v1/guests/stays/:id
  • GET /api/v1/guest_bookings/group_sizes

@zaydaanjahangir zaydaanjahangir marked this pull request as ready for review April 4, 2026 22:29
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 4, 2026

Codecov Report

❌ Patch coverage is 32.69231% with 140 lines in your changes missing coverage. Please review.
✅ Project coverage is 9.53%. Comparing base (c055973) to head (32ef258).
⚠️ Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
backend/internal/cache/readers.go 38.26% 55 Missing and 16 partials ⚠️
backend/internal/service/server.go 0.00% 26 Missing ⚠️
backend/internal/cache/json_cache.go 45.23% 18 Missing and 5 partials ⚠️
backend/internal/service/cached_repos.go 0.00% 16 Missing ⚠️
backend/cmd/server/main.go 0.00% 2 Missing ⚠️
backend/internal/storage/redis/client.go 71.42% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##            main    #280      +/-   ##
========================================
+ Coverage   2.02%   9.53%   +7.50%     
========================================
  Files         82     125      +43     
  Lines       3064    5455    +2391     
  Branches      24       0      -24     
========================================
+ Hits          62     520     +458     
- Misses      3002    4899    +1897     
- Partials       0      36      +36     
Flag Coverage Δ
backend 20.89% <32.69%> (?)
mobile ?
web 0.65% <ø> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
backend/cmd/server/main.go 0.00% <0.00%> (ø)
backend/internal/storage/redis/client.go 33.33% <71.42%> (ø)
backend/internal/service/cached_repos.go 0.00% <0.00%> (ø)
backend/internal/cache/json_cache.go 45.23% <45.23%> (ø)
backend/internal/service/server.go 0.00% <0.00%> (ø)
backend/internal/cache/readers.go 38.26% <38.26%> (ø)

... and 57 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@danctila danctila added feature Introduces a new and complete feature feat(urethon) labels Apr 4, 2026
Copy link
Copy Markdown
Contributor

@danctila danctila left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a couple cmmts

one thing i noticed was there isn't cache invalidation on writes. it looks like UpdateUser, UpdateProfilePicture, etc passthrough to the DB without touching the cache so a write followed by a read right after would return stale data until TTL dies. I think these need to delete or overwrite the cache key on sucess of. a write.


type CachedGuestsRepository struct {
cache *JSONCache
next storage.GuestsRepository
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all the other cached wrappers define a local interface for its next but this one imports directly from the pg package?

@zjahangir-chwy
Copy link
Copy Markdown

just a couple cmmts

one thing i noticed was there isn't cache invalidation on writes. it looks like UpdateUser, UpdateProfilePicture, etc passthrough to the DB without touching the cache so a write followed by a read right after would return stale data until TTL dies. I think these need to delete or overwrite the cache key on sucess of. a write.

Yeah, I'm pretty sure I avoided invalidation on the first phase out of simplicity. Since we're out of featurethon I'll update this with a more fleshed out implementation, probably over a couple PRs. Thx for review 🐐

Copy link
Copy Markdown
Contributor

@Dao-Ho Dao-Ho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some more cmts on top of Dylan's

require.NoError(t, err)
assert.Equal(t, "localhost:6379", cfg.Addr)
assert.Equal(t, "", cfg.Password)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would this test look in a prod container? 🤔

goredis "github.com/redis/go-redis/v9"
)

var ErrCacheMiss = errors.New("cache miss")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mv this to our err package

return
}
c.logger.Warn("redis cache write failed", "key", key, "err", err)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good but feels like this should be separated into two different layers.

One for the abstracted cache layer and the other for the Redis access itself.

Caller for our KV store shouldn't need to know how our Redis access works under the hood, also would just be good abstraction for future caching impl if we want to expand on it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changes requested feature Introduces a new and complete feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants